package DAO;

import java.io.Serializable;
import java.util.GregorianCalendar;
import java.util.List;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.PrimaryKeyJoinColumn;
import javax.persistence.Table;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;

import org.hibernate.Criteria;
import org.hibernate.Query;
import org.hibernate.Session;
import org.hibernate.Transaction;
import org.hibernate.criterion.Example;
import org.hibernate.criterion.Order;
import org.hibernate.criterion.Restrictions;

@Entity
@Table(name="dept_manager")
public class DepartmentManager implements Serializable {
	private int id;
	
	private GregorianCalendar from_date;
	private GregorianCalendar to_date;
	private Employee employee;
	private Department department;
	
	public DepartmentManager() {}
	public DepartmentManager(Employee employee, Department department, GregorianCalendar from_date,
			GregorianCalendar to_date) {
		this.employee = employee;
		this.department = department;
		this.from_date = from_date;
		this.to_date = to_date;

	}
//*******************************GETTERS SETTERS***********************************
	@Id
	@GeneratedValue
	@Column(name = "id")
	public int getId(){return id;}
	public void setId(int id){this.id = id;}

	@Column(name="from_date")
	public GregorianCalendar getFrom_date() {return from_date;}
	public void setFrom_date(GregorianCalendar from_date) {this.from_date = from_date;}

	@Column(name="to_date")
	public GregorianCalendar getTo_date() {return to_date;}
	public void setTo_date(GregorianCalendar to_date) {this.to_date = to_date;}
	
	
	@ManyToOne
	@JoinColumn(name="emp_no")
	public Employee getEmployee() {return employee;}
	public void setEmployee(Employee employee) {this.employee = employee;}

	@ManyToOne
	@JoinColumn(name="dept_no")
	public Department getDepartment() {return department;}
	public void setDepartment(Department department) {this.department = department;}

//****************************METHODS**********************************	
	public void print(){
		System.out.printf("%d, %s: from %s to %s\n", employee.getEmp_no(), department.getDept_no(), from_date.toString(), to_date.toString());
	}
	
//****************STATIC METHODS****************************************
	public static void add(DepartmentManager e){
    	Session session = HibernateContext.getSession();
    	Transaction tx = session.beginTransaction();
        {
        	session.save(e);
        }
        tx.commit();
        session.close();
        System.out.println("Department Added");
	}
	public static void load(){
    	Session session = HibernateContext.getSession();
    	
    	Employee ron = Employee.find("Ronald", "Mak");
    	Employee john = Employee.find("John", "Pierce");
    	
    	DepartmentManager r = new DepartmentManager(ron, Department.findByNum("d0001"), new GregorianCalendar(2005,6,5), new GregorianCalendar(2013, 2, 21));

    	
    	DepartmentManager j = new DepartmentManager(john, Department.findByNum("d0001"), new GregorianCalendar(2000,9,30), new GregorianCalendar(2013, 2, 21));

    	Transaction tx = session.beginTransaction();{
    		session.save(r);
    		session.save(j);
 
    	}
    	tx.commit();
    	session.close();
    	System.out.println("Department Manager has been loaded");
    }
	public static List<DepartmentManager> list(){
		
		Session session = HibernateContext.getSession();
		Criteria criteria = session.createCriteria(DepartmentManager.class);
		criteria.addOrder(Order.asc("emp_no"));
		
		List<DepartmentManager> mans = criteria.list();
		System.out.println("All Department Managers:");
		
		for(DepartmentManager m : mans){
			m.print();
		}
		session.close();
		return mans;
	}
	/*
	 * Gets department Manager by employee number and department number
	 */
	public static DepartmentManager find(long emp_no, String dept_no){
    	// Query using HQL.
        Session session = HibernateContext.getSession();
        Query query = session.createQuery("from DepartmentManager where emp_no = :idvar and dept_no = :deptvar");
        query.setLong("idvar", emp_no);
        query.setString("deptvar", dept_no);
        DepartmentManager d = (DepartmentManager) query.uniqueResult();
       
        session.close();
        return d;
	}
	
	public static void employeesOf(String dept_name){
		Session sess = HibernateContext.getSession();
		Criteria empCrit = sess.createCriteria(Employee.class);
		Criteria deptCrit = empCrit.createCriteria("department_manager");
		Criteria depart = deptCrit.createCriteria("department");
		
		depart.add(Restrictions.eq("dept_name", dept_name));
		
		empCrit.setResultTransformer(Criteria.DISTINCT_ROOT_ENTITY);
		empCrit.addOrder(Order.asc("emp_no"));
		
		List<Employee> emps = (List<Employee>) empCrit.list();
		System.out.println("Employees in " + dept_name + " department");
		for(Employee e: emps){
			System.out.printf("\t %s %s\n", e.getFirst_name(), e.getLast_name());
		}
	}
	

}
